exception InvalidFormat
let errord text () =
  let dlg = GWindow.message_dialog
    ~message:text
    ~destroy_with_parent:false
    ~use_markup:true
    ~message_type:`ERROR
    ~position:`CENTER_ON_PARENT
    ~buttons:GWindow.Buttons.ok
    ()
  in
  let _ = dlg#run () in
    dlg#destroy ();
    ()

let badFile =
  errord ("<b><big>Invalid color file!</big></b>\n\n Make sure your "^
  "colors-to-altitudes file matches with these colors.\n\n")

let badEntry =
  errord ("<b><big>Invalid values!</big></b>\n Make sure "^
  "you entered only numeric values.\n\n")




(* Boite de réglage de lacamera *)
class light_widget speed_call get_pos_fun set_pos_call () =
  let lightbox = GPack.vbox
    ~spacing:5
    ~border_width:5 ()
  in
  let speedadj = GData.adjustment
    ~value:5.0
    ~lower:5.0
    ~upper:500.0
    ~step_incr:5.0
    ~page_incr:100.0
    ~page_size:0.0
  in
  let speedbox = GPack.hbox
    ~spacing:5
    ~packing:lightbox#pack ()
  in
  let _ = GMisc.label
    ~text:"Speed :"
    ~xalign:0.0
    ~yalign:0.5
    ~packing:speedbox#pack ()
  in
  let speed = GEdit.spin_button
    ~digits:2
    ~adjustment:(speedadj ())
    ~numeric:true
    ~snap_to_ticks:true
    ~wrap:true
    ~rate:1.0
    ~packing:speedbox#pack ()
  in
  let speedbutton = GButton.button
    ~stock:`APPLY
    ~packing:speedbox#pack ()
  in
  let _ = GMisc.label
    ~text:"Saved camera positions :"
    ~xalign:0.0
    ~yalign:0.5
    ~packing:lightbox#pack ()
  in
  let scroll = GBin.scrolled_window
    ~hpolicy:`AUTOMATIC
    ~vpolicy:`AUTOMATIC
    ~packing:lightbox#add ()
  in
  let ffox = GPack.hbox
               ~packing:lightbox#pack
               ()
  in
  let _  = GMisc.label
              ~text:"Name: "
              ~packing:(ffox#add)
              ()
  in
  let edit = GEdit.entry
               ~packing:(ffox#add)
               ()
  in
    (* Un conteneur pour les boutons *)
  let bbox = GPack.button_box `VERTICAL
    ~layout:`SPREAD
    ~packing:(lightbox#pack ~expand:false) ()
  in
    (* Ajout du bouton pour ajouter une position de camera *)
  let addbutton = GButton.button
    ~label:" Add position "
    ~packing:bbox#pack ()
  in
let removebutton = GButton.button
    ~label:" Remove position "
    ~packing:bbox#pack ()
  in
  let importbutton = GButton.button
    ~label:" Import "
    ~packing:bbox#pack ()
  in
  let exportbutton = GButton.button
    ~label:" Export "
    ~packing:bbox#pack ()
  in
  let cols = new GTree.column_list
  in
  let col_name = cols#add Gobject.Data.string  (* string column *)
  and col_coordz = cols#add  Gobject.Data.float
  and col_coordy = cols#add  Gobject.Data.float
  and col_coordx = cols#add  Gobject.Data.float
  and col_coorddz = cols#add  Gobject.Data.float
  and col_coorddy = cols#add  Gobject.Data.float
  and col_coorddx = cols#add  Gobject.Data.float
  in

object (self)
  val store = GTree.list_store cols
  method get_box () =
    lightbox

  method file_choose f title opentype othertype ()=
    let fs = GWindow.file_chooser_dialog
               ~action:opentype
               ~title:title
               ~modal: true
               ~position:`CENTER_ON_PARENT
               ()
    in
      begin
        fs#add_select_button_stock othertype `SAVE;
        if(fs#run () = `SAVE) then
          begin
            (
              match fs#filename with
                | Some(s) ->
                    f s
                | _ -> ()
            );
          end;
        fs#destroy ();
      end



  method to_file path =
    let out = open_out path
    in
    let f (model:GTree.list_store) path iter =
      let (s,((x,y,z),(dx,dy,dz))) =
        (model#get ~row:iter ~column:col_name,
         ((model#get ~row:iter ~column:col_coordx,
         model#get ~row:iter ~column:col_coordz,
         model#get ~row:iter ~column:col_coordy
        ),(
          (model#get ~row:iter ~column:col_coorddx),
          (model#get ~row:iter ~column:col_coorddy),
          (model#get ~row:iter ~column:col_coorddz))))
      in
        Printf.fprintf out "%s|*|%f|*|%f|*|%f|*|%f|*|%f|*|%f\n"
          s x y z dx dy dz;
        false
    in
    store#foreach (f store);
    close_out out

  method from_file path =
    let buf = open_in path in
      try
        while true do
          match Str.split (Str.regexp_string "|*|") (input_line buf) with
            | n::x::y::z::dx::dy::dz::[] ->
                self#add_row (n,
                         ((float_of_string x,
                          float_of_string y,
                          float_of_string z),
                          (float_of_string dx,
                           float_of_string dy,
                           float_of_string dz)
                         )
                )
            | _ -> raise  InvalidFormat
        done
      with _ -> close_in buf;
    ()

  method add_row (name,((x,y,z),(dx,dy,dz))) =
      let iter = store#append () in
	store#set ~row:iter ~column:col_name (if name="" then"New pos" else name);
	store#set ~row:iter ~column:col_coordx x;
	store#set ~row:iter ~column:col_coordy y;
	store#set ~row:iter ~column:col_coordz z;
	store#set ~row:iter ~column:col_coorddx dx;
	store#set ~row:iter ~column:col_coorddy dy;
	store#set ~row:iter ~column:col_coorddz dz

  method add_new_pos () =
    let ((x,y,z),(dx,dy,dz)) = get_pos_fun () in
      self#add_row (edit#text,((x,z,y),(dx,dy,dz)))

  method remove_current_row model selection () =
    let rm path =
      let row = model#get_iter path
      in
        ignore(store#remove row);
        ()
    in
      List.iter rm selection#get_selected_rows

  method activate_view (view:GTree.view) path column =
    let model = view#model
    in
    let row = model#get_iter path
    in
    let ((x,y,z),(dx,dy,dz)) as npos = (
      (
      model#get ~row ~column:col_coordx,
      model#get ~row ~column:col_coordz,
      model#get ~row ~column:col_coordy
      ),(
      (model#get ~row ~column:col_coorddx),
      (model#get ~row ~column:col_coorddy),
      (model#get ~row ~column:col_coorddz)
    ))
    in
      set_pos_call npos;
      ()

  method create_view ~model ~packing () =
    let view = GTree.view ~model ~packing () in
    let col = GTree.view_column ~title:"Name"
                ~renderer:(GTree.cell_renderer_text [],
                           ["text", col_name]) ()
    in
      ignore (view#append_column col);
      let col = GTree.view_column ~title:"X"
                  ~renderer:(GTree.cell_renderer_text [],
                             ["text", col_coordx]) ()
      in
        ignore (view#append_column col);
        let col = GTree.view_column ~title:"Y"
                    ~renderer:(GTree.cell_renderer_text [],
                               ["text", col_coordy]) ()
        in
          ignore (view#append_column col);
          let col = GTree.view_column ~title:"Z"
                      ~renderer:(GTree.cell_renderer_text [],
                                 ["text", col_coordz]) ()
          in
            ignore (view#append_column col);
          let col = GTree.view_column ~title:"dir-X"
                      ~renderer:(GTree.cell_renderer_text [],
                                 ["text", col_coorddx]) ()
          in
            ignore (view#append_column col);
          let col = GTree.view_column ~title:"dir-Y"
                      ~renderer:(GTree.cell_renderer_text [],
                                 ["text", col_coorddy]) ()
          in
            ignore (view#append_column col);
          let col = GTree.view_column ~title:"dir-Z"
                      ~renderer:(GTree.cell_renderer_text [],
                                 ["text", col_coorddz]) ()
          in
            ignore (view#append_column col);
            view



  method init () =
    ignore(speedbutton#connect#clicked
             ~callback: (fun () -> speed_call speed#value; ()));
    ignore(addbutton#connect#clicked ~callback:self#add_new_pos);
    ignore(importbutton#connect#clicked
             ~callback:(self#file_choose self#from_file
                          "Import positions file" `OPEN `OPEN ));
    ignore(exportbutton#connect#clicked
             ~callback:(self#file_choose self#to_file
                          "Export positions file" `SAVE `SAVE ));
    let v = self#create_view ~model:store ~packing:scroll#add ()
    in
      ignore(removebutton#connect#clicked
               ~callback:(self#remove_current_row v#model v#selection));
      v#connect#row_activated ~callback:(self#activate_view v)


end

let get_lightings_widgets_contener speed_call get_pos set_pos () =
  let box = new light_widget speed_call get_pos set_pos () in
    ignore(box#init ());
    box#get_box ()



(* Boite des autres données (tau échelle) *)
class option_widget tau slope scaleval applycall () =
  let optionbox = GPack.vbox
    ~spacing:5
    ~border_width:15 ()
  in
  let adj l u init = GData.adjustment
    ~value:init
    ~lower:l
    ~upper:u
    ~step_incr:1.0
    ~page_incr:100.0
    ~page_size:0.0
  in
  let _ = GMisc.label
    ~text:"Slope :"
    ~xalign:0.0
    ~yalign:0.5
    ~packing:optionbox#pack ()
  in
  let tauhbox = GPack.hbox
    ~spacing:5
    ~packing:optionbox#pack ()
  in
  let tau = GEdit.spin_button
    ~digits:2
    ~adjustment:(adj 1. 100. 2. ())
    ~numeric:true
    ~snap_to_ticks:true
    ~wrap:true
    ~rate:1.0
    ~value:tau
    ~packing:tauhbox#pack ()
  in
  let adj2 low = GData.adjustment
    ~value:low
    ~lower:low
    ~upper:1000.0
    ~step_incr:1.0
    ~page_incr:100.0
    ~page_size:0.0
  in
  let _ = GMisc.label
    ~text:"Accuracy :"
    ~xalign:0.0
    ~yalign:0.5
    ~packing:optionbox#pack ()
  in
  let scalehbox = GPack.hbox
    ~spacing:5
    ~packing:optionbox#pack ()
  in
  let scale = GEdit.spin_button
    ~digits:2
    ~adjustment:(adj2 2.0 ())
    ~numeric:true
    ~snap_to_ticks:true
    ~wrap:true
    ~rate:1.0
    ~value:slope
    ~packing:scalehbox#pack ()
  in
  let _ = GMisc.label
    ~text:"Scale :"
    ~xalign:0.0
    ~yalign:0.5
    ~packing:optionbox#pack ()
  in
  let realscalescalehbox = GPack.hbox
    ~spacing:5
    ~packing:optionbox#pack ()
  in
  let realscale = GEdit.spin_button
    ~digits:2
    ~adjustment:(adj2 1.0 ())
    ~numeric:true
    ~snap_to_ticks:true
    ~wrap:true
    ~rate:1.0
    ~value:scaleval
    ~packing:realscalescalehbox#pack ()
  in

  let scalebutton = GButton.button
    ~stock:`APPLY
    ~packing:optionbox#pack ()
  in
object
  method get_box () =
    optionbox
  method init () =
    scalebutton#connect#clicked
      ~callback: (fun _ -> applycall tau#value scale#value
                             realscale#value ())

end


let get_generaldatas_widgets_contener tau slope scale applycall () =
  let box = new option_widget tau slope scale applycall () in
    ignore(box#init ());
    box#get_box ()



exception ErrorList

(* Boite des attributs alt<->couleurs
 * path = chemin de fichier choisi par
 * l'utilisateur lors de l'ouverture d'
 * un fichier.
 * Si le fichier est invalide, il ne faut
 * pas gérer l'exception qui remontera
 * vers un handler plus haut dans les appels.
 *)
class color_widget colorspath colors_changed () =

(* Boite qui contient le reste *)
  let path = colorspath
  in
  let vbox, packing =
    let vbox = GPack.vbox
                 ~spacing:5
                 ~border_width:5 () in
      vbox, vbox#pack ~expand:false
  in

  (* Insertion de barres de defilement. *)
  let scroll = GBin.scrolled_window
                 ~hpolicy:`AUTOMATIC
                 ~vpolicy:`AUTOMATIC
                 ~packing:vbox#add ()
  in


  (* Creation du tableau d'affichage des couleurs *)
  let attach =
    let table = GPack.table
                  ~rows:4
                  ~columns:4
                  ~row_spacings:5
                  ~col_spacings:5
                  (* ~homogeneous:true *)
                  ~packing:scroll#add_with_viewport () in
      fun i -> table#attach ~left:(0) ~top:(i)
  in


  (* Un conteneur pour les boutons *)
  let bbox = GPack.button_box `HORIZONTAL
               ~layout:`SPREAD
               ~packing:(vbox#pack ~expand:false) ()
  in


  (* Ajout du bouton pour importer un fichier altitude *)
  let button = GButton.button
                 ~stock:`OPEN
                 ~packing:bbox#pack ()
  in
  (* Bouton pour appliquer les nouvelles valeurs du tableau *)
  let register = GButton.button
                   ~stock:`APPLY
                   ~packing:bbox#pack ()
  in


object (self)

  (* Fonction de tri des differentes valeurs entrees *)
  method sort_entry b1 b2 =
    let (e1,_,_,_) = b1 in
    let (e2,_,_,_) = b2 in
    let v1 = float_of_string e1#text in
    let v2 = float_of_string e2#text in
      if (v1 > v2) then
        1
      else if (v2 > v1) then
       -1
      else
        0


  (*  Fonction d'ecriture des valeurs entrees dans un fichier texte *)
  method write_entries list =
    let exit_chan = open_out path
    in
    let rec write list = match list with
        [] -> ()
      | (entry,r,g,b)::l ->
          let value = entry#text in
            begin
              output (exit_chan) (string_of_int r) (0)
                (String.length(string_of_int r));
              output (exit_chan) (" ") (0) (1);
              output (exit_chan) (string_of_int g) (0)
                (String.length(string_of_int g));
              output (exit_chan) (" ") (0) (1);
              output (exit_chan) (string_of_int b) (0)
                (String.length(string_of_int b));
              output (exit_chan) (" : ") (0) (3);
              output (exit_chan) (value) (0)
                (String.length(value));
              output (exit_chan) ("\n") (0) (1);
              output (exit_chan) (" ") (0) (1);
              flush exit_chan;
              write l;
            end
    in
      write list


  method extract_entries (l:(GEdit.entry*int*int*int) list) =
    match l with
    |[] -> []
    | (e,r,g,b)::q ->
        ((r,g,b),float_of_string e#text)::self#extract_entries q
  (* Creation du tableau qui affiche les couleurs et recupere leur
   valeur *)
  method init_table colors valuelist =
    let listtext = ref [] in
let valuearray = (Array.of_list valuelist) in
  for i = 0 to ((Array.length colors) -1) do
    let (r,g,b) = colors.(i) in
    let text = Printf.sprintf "#%02x%02x%02x" r g b in
    let entry = GEdit.entry
                  ~text:((string_of_float(valuearray.(i))) ^ "0")
                  ~packing:(attach i) () in
      entry#misc#modify_base [`NORMAL, `NAME text];
      listtext:=(entry,r,g,b)::!listtext;
  done;
  ignore(register#connect#clicked ~callback:
           begin
             function _->
               try
               listtext := List.sort self#sort_entry !listtext;
               self#write_entries !listtext;
               colors_changed (self#extract_entries !listtext) ();
               with
                _-> badEntry ()
           end
  )

  method get_colorlist covlist =
    let rec get_colorlistrec cvlist = match cvlist with
      | [] -> []
      | ((r,g,b),_)::l -> (r,g,b)::(get_colorlistrec l)
    in
      get_colorlistrec covlist

  method get_valuelist covlist =
    let rec get_valuelistrec cvlist = match cvlist with
      | [] -> []
      | (_, h)::l -> (h)::(get_valuelistrec l)
    in
      get_valuelistrec covlist


  (* Fonction qui appelle le module pour recuperer les couleurs *)
  method open_colors colorvaluelist =
    begin
      self#init_table
        (Array.of_list(self#get_colorlist(colorvaluelist)))
        (self#get_valuelist(colorvaluelist));
    end

  method get_box () =
    vbox

  (* Fonctions pour parser le fichier est afficher les valeurs courantes *)
  method convert_parse i array list =
    let rec convert i array list = match list with
        [] -> ()
      | hd::l -> array.(i) <- hd; convert (i+1) array l
    in
      convert i array list

  method parse_values path =
    let canal = open_in path in
    let listline = Array.make 50 "" in
    let legend = ref [] in
    let l = ref (input_line canal) in
    let i = ref 0 in
      while (!l <> " ") do
        listline.(!i) <- !l;
        i := !i + 1;
        l := input_line canal;
      done;
      let j = ref 0 in
        while !j < !i do
          let hd = listline.(!j) in
            j := !j + 1;
            let split = Str.split (Str.regexp " ") hd in
            let splitarray = Array.make 5 "" in
              self#convert_parse 0 splitarray split;
              let r = int_of_string splitarray.(0) in
              let g = int_of_string splitarray.(1) in
              let b = int_of_string splitarray.(2) in
              let h = float_of_string splitarray.(4) in
              let newvalue = ((r,g,b), h) in
                legend := newvalue::!legend;
        done;
        List.rev !legend

  method equal list1 list2 =
    let rec equalrec l1 l2 = match l1 with
      | [] -> true
      | e::l -> (List.mem e l2) && equalrec l l2
    in
      equalrec list1 list2

  method choosealt path () =
    let dlg = GWindow.file_chooser_dialog
                ~action:`OPEN
                ~position:`CENTER
                ~destroy_with_parent:true ()
    in
      dlg#add_button_stock `CANCEL `CANCEL;
      dlg#add_select_button_stock `OPEN `OPEN;
      if (dlg#run () = `OPEN) then
        match dlg#filename with
          | Some(s) ->
              (
                try
                if (self#equal
                      (self#get_colorlist(self#parse_values(path)))
                      (self#get_colorlist(self#parse_values(s))))
                then
                  self#init_table
                    (Array.of_list(
                      self#get_colorlist(self#parse_values(path))))
                    (self#get_valuelist(self#parse_values(s)));
                dlg#destroy ()
                with _ -> dlg#destroy (); badFile ()
              )
          | _ -> ()


  method init path =
    ignore(button#connect#clicked ~callback:(self#choosealt path))

end



let get_colorselect_widgets_contener path colorschanged =
  let box = new color_widget path colorschanged () in
  let colorvaluelist = ref [] in
    colorvaluelist := (box#parse_values path);
    box#open_colors !colorvaluelist;
    box#init path;
    box#get_box ()





(* Classe puis fonction d'appel correspondants a la 'grosse' boite qui
   contient le choix de la valeur des couleurs par l'utilisateur. La
   fonction d'appel requiert le chemin du fichier et renvoie la boite
   avec le tableau des couleurs affiche *)
class big_color_widget savecall colorsValuesPath =

  (* Boite qui contient le reste *)
  let path = colorsValuesPath in
  let vbox, packing =
    let vbox = GPack.vbox
      ~spacing:5
      ~border_width:5 () in
      vbox, vbox#add
  in
  let _ = GMisc.label
    ~text:"Choose a value for each color on the map :"
    ~use_underline:true
    ~packing:(vbox#pack ~expand:false) ()
  in
  let hbox = GPack.hbox
    ~spacing:5
    ~border_width:5
    ~packing:vbox#add ()
  in
  (* Insertion de barres de defilement. *)
  let scroll = GBin.scrolled_window
    ~hpolicy:`AUTOMATIC
    ~vpolicy:`AUTOMATIC
    ~width:550
    ~height:500
    ~packing:hbox#add ()
  in



  (* Creation du tableau d'affichage des couleurs *)
  let attach =
    let table = GPack.table
      ~rows:4
      ~columns:4
      ~row_spacings:5
      ~col_spacings:5
      (* ~homogeneous:true *)
      ~packing:scroll#add_with_viewport () in
      fun i -> table#attach ~left:(i mod 3) ~top:(i / 3)
  in


  (* Un conteneur pour les boutons *)
  let bbox = GPack.button_box `HORIZONTAL
    ~layout:`SPREAD
    ~packing:(vbox#pack ~expand:false) ()
  in

  (* Ajout du bouton pour importer un fichier altitude *)
    let button = GButton.button
      ~stock:`OPEN
      ~packing:bbox#pack ()
  in
  let optionbox = GPack.vbox
    ~spacing:5
    ~packing:hbox#pack ()
  in
  let adj v l u= GData.adjustment
    ~value:v
    ~lower:l
    ~upper:u
    ~step_incr:1.0
    ~page_incr:100.0
    ~page_size:0.0
  in
  let _ = GMisc.label
    ~text:"Slope :"
    ~xalign:0.0
    ~yalign:0.5
    ~packing:optionbox#pack ()
  in
  let tauhbox = GPack.hbox
    ~spacing:5
    ~packing:optionbox#pack ()
  in
  let tau = GEdit.spin_button
    ~digits:2
    ~adjustment:(adj 2. 1. 100. ())
    ~numeric:true
    ~snap_to_ticks:true
    ~wrap:true
    ~rate:1.0
    ~packing:tauhbox#pack ()
  in
  let adj2 low  = GData.adjustment
    ~value:low
    ~lower:low
    ~upper:1000.0
    ~step_incr:1.0
    ~page_incr:100.0
    ~page_size:0.0
  in
  let _ = GMisc.label
    ~text:"Accuracy :"
    ~xalign:0.0
    ~yalign:0.5
    ~packing:optionbox#pack ()
  in
  let scalehbox = GPack.hbox
    ~spacing:5
    ~packing:optionbox#pack ()
  in
  let scale = GEdit.spin_button
    ~digits:2
    ~adjustment:(adj2 2.0 ())
    ~numeric:true
    ~snap_to_ticks:true
    ~wrap:true
    ~rate:1.0
    ~packing:scalehbox#pack ()
  in
let _ = GMisc.label
    ~text:"Scale :"
    ~xalign:0.0
    ~yalign:0.5
    ~packing:optionbox#pack ()
  in
  let realscalescalehbox = GPack.hbox
    ~spacing:5
    ~packing:optionbox#pack ()
  in
  let realscale = GEdit.spin_button
    ~digits:2
    ~adjustment:(adj2 1.0 ())
    ~numeric:true
    ~snap_to_ticks:true
    ~wrap:true
    ~rate:1.0
    ~packing:realscalescalehbox#pack ()
  in
    (* Bouton pour appliquer les nouvelles valeurs du tableau *)
  let register = GButton.button
    ~stock:`APPLY
    ~packing:bbox#pack ()
  in

object (self)

  val mutable boolcallback = true
  (* Fonction de tri des differentes valeurs entrees *)
  method sort_entry b1 b2 =
    let (e1,_,_,_) = b1 in
    let (e2,_,_,_) = b2 in
    let v1 = float_of_string e1#text in
    let v2 = float_of_string e2#text in
      if (v1 > v2) then
	1
      else if (v2 > v1) then
	-1
      else
	0

  (* Fonction d'ecriture des valeurs entrees dans un fichier texte *)
  method write_entries list =
    let exit_chan = open_out path in
    let rec write exit_chan list = match list with
	[] -> ()
      | (entry,r,g,b)::l ->
          let value = entry#text in
            begin
              output (exit_chan) (string_of_int r) (0)
		(String.length(string_of_int r));
              output (exit_chan) (" ") (0) (1);
              output (exit_chan) (string_of_int g) (0)
		(String.length(string_of_int g));
              output (exit_chan) (" ") (0) (1);
	      output (exit_chan) (string_of_int b) (0)
		(String.length(string_of_int b));
	      output (exit_chan) (" : ") (0) (3);
	      output (exit_chan) (value) (0)
		(String.length(value));
	      output (exit_chan) ("\n") (0) (1);
	      output (exit_chan) (" ") (0) (1);
	      flush exit_chan;
	      write exit_chan l;
	    end
    in
      write exit_chan list


  (* Creation du tableau qui affiche les couleurs et recupere leur
     valeur *)
  method init_table colors valuelist =
    let valuearray = (Array.of_list valuelist) in
    let listtext = ref [] in
      for i = 0 to ((Array.length colors) -1) do
	let (r,g,b) = colors.(i) in
	let text = Printf.sprintf "#%02x%02x%02x" r g b in
	let entry = GEdit.entry
	  ~text:((string_of_float(valuearray.(i))) ^ "0")
	  ~packing:(attach i) () in
	  entry#misc#modify_base [`NORMAL, `NAME text];
	  listtext:=(entry,r,g,b)::!listtext;
      done;
      ignore(register#connect#clicked ~callback:
               begin
		 function _->
                   try
                     listtext := List.sort self#sort_entry !listtext;
                     self#write_entries !listtext;
                     if (boolcallback) then
                       savecall tau#value scale#value realscale#value
                     else
                       boolcallback <- true
                   with _ ->
                     badEntry ()

               end
            )



  (* Fonction qui appelle le module pour recuperer les couleurs *)
  method open_colors filepath =
    let (colors,labels,labelscols) = Colors.maincolor(filepath)
    in
    let colorarray = Array.of_list(colors)
    in
    let listvalue = Array.make (Array.length colorarray) 0.
    in
      self#init_table colorarray (Array.to_list listvalue);
      (labels,labelscols)

  method get_box () =
    vbox

  method get_colorlist covlist =
    let rec get_colorlistrec cvlist = match cvlist with
      | [] -> []
      | ((r,g,b),_)::l -> (r,g,b)::(get_colorlistrec l)
    in
      get_colorlistrec covlist

  method get_valuelist covlist =
    let rec get_valuelistrec cvlist = match cvlist with
      | [] -> []
      | (_, h)::l -> (h)::(get_valuelistrec l)
    in
      get_valuelistrec covlist


(* Fonctions pour parser le fichier est afficher les valeurs
   courantes *)
  method convert_parse i array list =
    let rec convert i array list = match list with
	[] -> ()
      | hd::l -> array.(i) <- hd; convert (i+1) array l
    in
      convert i array list

  method parse_values path =
    let canal = open_in path in
    let listline = Array.make 50 "" in
    let legend = ref [] in
    let l = ref (input_line canal) in
    let i = ref 0 in
      while (!l <> " ") do
	listline.(!i) <- !l;
        i := !i + 1;
	l := input_line canal;
      done;
      let j = ref 0 in
	while !j < !i do
          let hd = listline.(!j) in
            j := !j + 1;
            let split = Str.split (Str.regexp " ") hd in
            let splitarray = Array.make 5 "" in
              self#convert_parse 0 splitarray split;
              let r = int_of_string splitarray.(0) in
              let g = int_of_string splitarray.(1) in
              let b = int_of_string splitarray.(2) in
              let h = float_of_string splitarray.(4) in
              let newvalue = ((r,g,b), h) in
                legend := newvalue::!legend;
	done;
        List.rev !legend


  method choosealt () =
    let dlg = GWindow.file_chooser_dialog
      ~action:`OPEN
      ~position:`CENTER
      ~destroy_with_parent:true ()
    in
      dlg#add_button_stock `CANCEL `CANCEL;
      dlg#add_select_button_stock `OPEN `OPEN;
      if (dlg#run () = `OPEN) then
	match dlg#filename with
          | Some(s) ->
	      (
                try
		boolcallback <- false;
		self#init_table
		  (Array.of_list(self#get_colorlist(self#parse_values(s))))
		  (self#get_valuelist(self#parse_values(s)));
		dlg#destroy ()
                with _->dlg#destroy (); badFile ()
	      )
          | _ -> ()


  method init () =
    ignore(button#connect#clicked ~callback:(self#choosealt))

end


let get_bigcolorselect savecall path colorsValuesPath=
  let box = new big_color_widget savecall colorsValuesPath in
  let (labels,labelsc) = box#open_colors path
  in
    box#init();
    (box#get_box (),labels,labelsc)
